package MathTextModeller
{
	import MathText.WordProblem;
	
	import MyDisplayObjects.DraggableImage;
	import MyDisplayObjects.DraggableMC;
	
	import TaskStructure.LogEvent;
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class SentenceDisplay extends MovieClip
	{
		private var otherMCs:Array = null; // all other objects, containers, etc.
		private var unitMCs:Array = null; // the unit objects (e.g., marbles)
		private var variableMC:DraggableMC = null; // the variable
		private var backgroundMC:DraggableMC = null;
		private var combineMC:DraggableMC=null, changeMC:DraggableMC=null, compareMC:DraggableMC=null;
		private var curMC:DraggableMC;
		private var curImageType:String;
		private var WIDTH:Number, HEIGHT:Number;
		private var wordProblem:WordProblem;
		// accessible
		private var _scale:Number;
		// getters
		public function get numUnits():uint{if (unitMCs != null){return unitMCs.length} else {return 0;}}
		public function get numOthers():uint{if (otherMCs != null){return otherMCs.length} else {return 0;}}
		public function get numVariables():uint{if (variableMC != null){return 1;} else {return 0;}}
		public function get hasCombine():Boolean{ if (combineMC != null){return true;} else {return false;}}
		public function get hasCompare():Boolean{ if (compareMC != null){return true;} else {return false;}}
		public function get hasChange():Boolean{ if (changeMC != null){return true;} else {return false;}}
		public function getUnitAt(i:uint):DraggableMC{if (unitMCs != null && i < unitMCs.length){return unitMCs[i]} else { return null;}}
		public function getUnitCoordsAt(i:uint):Point{if (unitMCs != null && i < unitMCs.length){return new Point(unitMCs[i].x, unitMCs[i].y);} else { return null;}}
		public function get panelScale():Number{return _scale;}
		public function set panelScale(s:Number):void
		{
			// scale
			this._scale = s
			this.scaleX = s;
			this.scaleY = s;
		}
		
		public function SentenceDisplay(width:Number, height:Number, wordProblem:WordProblem)
		{
			this.WIDTH = width;
			this.HEIGHT = height;
			this.wordProblem = wordProblem;
			this.graphics.lineStyle(width/200, 0x888888);
			this.graphics.beginFill(0xFCFFFC, 1);
			this.graphics.drawRect(0, 0, width, height);
			this.graphics.endFill();
			otherMCs = new Array();
			unitMCs = new Array();
		}
		
		/** imageName is the name of the image file, imageType is the type of object it is (unit, subject, unknown, etc) */
		public function addImageToDisplay(imageName:String, imageType:String, constrainProportions:Boolean = true):void
		{
			curImageType = imageType;
			var BORDERED_WIDTH:Number = this.width - this.width/16;
			if (imageType == "unit")
			{
				curMC = new DraggableImage(BORDERED_WIDTH/10, BORDERED_WIDTH/10, imageName, true, 2);
			} else if (imageType == "subject1" || imageType == "subject2")
			{
				curMC = new DraggableImage(BORDERED_WIDTH*2/5, BORDERED_WIDTH*2*5/12, imageName);
			}
			else if (imageType == "combined" || imageType == "changed" || imageType == "compared")
			{
				curMC = new DraggableImage(BORDERED_WIDTH, BORDERED_WIDTH*2/3, imageName);
			}else if (imageType == "variable" || imageType == "unknown")
			{
				curMC = new DraggableImage(BORDERED_WIDTH/5, BORDERED_WIDTH/5, imageName);
			}else if (imageType == "background")
			{
				curMC = new DraggableImage(this.width, this.height, imageName, constrainProportions);
			}else
			{
				curMC = new DraggableImage(BORDERED_WIDTH, BORDERED_WIDTH*2/3, imageName);
			}
			curMC.name = imageType;
			curMC.addEventListener( Event.COMPLETE, _addImageToDisplay);			
		}
		private function _addImageToDisplay (event:Event):void
		{
			curMC.removeEventListener( Event.COMPLETE, _addImageToDisplay);
			var dmc:DraggableMC = curMC; var imageType:String = curImageType;
			if (imageType == "unit")
			{
				dmc.type = "unit";
				var offsetX:Number = dmc.width + dmc.width/4;
				var offsetY:Number = dmc.height + dmc.height/4;
				unitMCs.push(dmc);
				this.addChild(dmc);
				// position in growing square
				dmc.moveSquareFromPoint(new Point((this.width - dmc.width)/2, (this.height - dmc.height)/2), unitMCs.length-1, 1.25);	
				dmc.origin = new Point(dmc.x, dmc.y);		
				dmc.addEventListener(MouseEvent.MOUSE_DOWN, handleDraggingStarted);
			} else if (imageType == "unknown" || imageType == "variable")
			{
				dmc.type = "variable";
				variableMC = dmc;
				if (backgroundMC == null)
				{
					this.addChildAt(dmc, otherMCs.length);
				} else
				{
					this.addChildAt(dmc, otherMCs.length+1);
				}
				dmc.x = (this.width - dmc.width)/2;
				dmc.y = (this.height - dmc.height)/2;
				dmc.origin = new Point(dmc.x, dmc.y);
			} else if (imageType == "background")
			{
				dmc.type = "background";
				backgroundMC = dmc;
				dmc.disabled = true;
				dmc.mouseEnabled = false;
				this.addChildAt(dmc, 0);
			}
			else 
			{
				dmc.type = "other";
				otherMCs.push(dmc);
				if (backgroundMC != null) {this.addChildAt(dmc, 1);}
				else {this.addChildAt(dmc, 0);}	
				if (imageType == "subject1")
				{
					dmc.addTextLabel(wordProblem.subject1.name, this.width/25, 0x000000);
				} else if (imageType == "subject2")
				{
					dmc.addTextLabel(wordProblem.subject2.name, this.width/25, 0x000000);
				} else if (imageType == "compared" || imageType == "combined" || imageType == "changed" || imageType == wordProblem.subject1.getAnyAVerb() || imageType == wordProblem.subject3.name)
				{
					if (imageType == "compared"){ compareMC = dmc; }
					else if (imageType == "changed" || imageType == wordProblem.subject1.getAnyAVerb() ){ changeMC = dmc; }
					else if (imageType == "combined"){ combineMC = dmc; }
					dmc.addTextLabel(wordProblem.subject1.name, this.width/25, 0x000000, DraggableMC.FRONT, DraggableMC.CENTER, this.width/40, 0);
					dmc.addTextLabel(wordProblem.subject2.name, this.width/25, 0x000000, DraggableMC.BACK, DraggableMC.CENTER, this.width/40, 0);
				} 
				dmc.x = (this.width - dmc.width)/2;
				dmc.y = (this.height - dmc.height)/2;
			}	
			// change the draggingBounds so we can move across entire display
			if (dmc != backgroundMC) 
			{
				dmc.draggingBounds = new Rectangle(0, 0, parent.width-this.x-dmc.width, this.height-dmc.height);
				this.dispatchEvent(new LogEvent(LogEvent.OBJECT_ADDED, imageType, this.name, dmc.x, dmc.y));
	
			}
			// add a dragging listener so that we can make sure the object was dragged in bounds
			dmc.addEventListener(MouseEvent.MOUSE_UP, handleDraggingComplete);
		}
		private function handleDraggingStarted (event:MouseEvent):void
		{
			var dmc:DraggableMC = DraggableMC(event.currentTarget);
			if (dmc.type == "unit")
			{
				this.removeChild(dmc);
				this.addChild(dmc);
			}
		}
		/** If dragging occurred and stopped out of bounds remove from screen */
		private function handleDraggingComplete (event:MouseEvent):void
		{
			var dmc:DraggableMC = DraggableMC(event.currentTarget);
			// are we within bounds?
			if (dmc.x > this.WIDTH - dmc.width)
			{ // out of bounds			
				
				if (dmc.type == "unit"){ unitMCs.splice(unitMCs.indexOf(dmc), 1); }
				else if (dmc.type == "variable" || dmc.type == "unknown"){variableMC = null;}
				else if (dmc.type == "background"){backgroundMC = null;}
				else if (dmc.type == "other")
				{ 
					otherMCs.splice(otherMCs.indexOf(dmc), 1); 
					if (dmc == combineMC){ combineMC = null;}
					if (dmc == changeMC){ changeMC = null;}
					if (dmc == compareMC){ compareMC = null;}
				}
				this.dispatchEvent(new LogEvent(LogEvent.OBJECT_REMOVED, dmc.name, this.name, dmc.x, dmc.y));
				this.removeChild(dmc);				
			} else
			{ // within bounds
				// are we overlapping any other objects?
				var overlapping:Boolean = false;
				for each (var odmc:DraggableMC in unitMCs)
				{
					if (dmc != odmc && (dmc.hitTestObject(odmc) || odmc.hitTestObject(dmc)))
					{
						overlapping = true;
					}
				}
				if (overlapping)
				{
					dmc.x = dmc.origin.x;
					dmc.y = dmc.origin.y;
					dmc.origin = new Point(dmc.x, dmc.y);
				} else
				{
					dmc.origin = new Point(dmc.x, dmc.y);
					this.dispatchEvent(new LogEvent(LogEvent.OBJECT_MOVED, dmc.name, this.name, dmc.x, dmc.y));
				}
			}
		}
		
		/** When this object is placed on the side-by-side panel the objects all must be scaled.
		 * All unit images are added to parent display, as well as variableImage.  Placed in corresponding place on parent object 
		 */ 
		public function transitionToPanelView(sentenceDisplayPanel:SentenceDisplayPanel):void
		{
			
			var cx:Number, cy:Number;
			// go through each unit object and place on parent
			for each (var dmc:DraggableMC in unitMCs)
			{
				cx = dmc.x; cy = dmc.y;
				dmc.alpha = 0;
				dmc.disabled = true;	
				sentenceDisplayPanel.addUnitMC(dmc.duplicate(), this);
				
			}				
			if (variableMC != null) 
			{
				cx = variableMC.x; cy = variableMC.y;
				variableMC.disabled = true;
				sentenceDisplayPanel.addVariableMC(variableMC.duplicate(), this);
			}	
			if (backgroundMC != null)
			{
				backgroundMC.disabled = true;
				backgroundMC.mouseEnabled = false;
			}
			for each (dmc in otherMCs)
			{
				dmc.disabled = true;
			}				
		}
		
		/** This method is called when we return from panel view back to seeing just the single display, rescale everything */
		public function transitionFromPanelView():void
		{
			this.scaleX /= _scale;
			this.scaleY /= _scale;
			// go through each unit object and place on parent
			for each (var dmc:DraggableMC in unitMCs)
			{
				dmc.alpha = 1;
				dmc.disabled = false;	
			}
			if (variableMC != null) 
			{
				variableMC.disabled = false;
			}
			if (backgroundMC != null)
			{
				backgroundMC.disabled = true;
			}
			for each (dmc in otherMCs)
			{
				dmc.disabled = false;
			}	
		}
	}
}